package com.lxj.zuul.config;

import com.lxj.utils.common.CommonResult;
import com.lxj.utils.util.JwtTokenUtil;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import io.jsonwebtoken.ExpiredJwtException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Set;

@Component
public class LogFilter extends ZuulFilter {

    @Value("#{'${pathlist}'.split(',')}")
    private List<String> pathlist;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Override
    public String filterType() {
        // 登录校验的过滤级别，肯定是第一层过滤
        return "pre";
    }

    @Override
    public int filterOrder() {
        // 执行顺序为1，值越小执行顺行越靠前
        return 1;
    }
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 登录校验过滤器，执行逻辑的方法
     *
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        /**
         * 登录逻辑校验：
         * 1、获取zuul提供的请求上下文对象（即使全部请求内容）
         * 2、从上下文中获取request对象
         * 3、从请求中获取token
         * 4、判断，如果没有token，则认为用户还没有登陆，返回401；
         *    如果用户通过，可以考虑把用户信息放入上下文，继续向后执行；
         */
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletResponse response = requestContext.getResponse();
        response.setContentType("text/html;charset=UTF-8");
        HttpServletRequest request = requestContext.getRequest();
        String uri = request.getRequestURI();
        //那些路径可以直接放行
        boolean a = pathlist.stream().anyMatch(path -> StringUtils.contains(uri, path));
        if (a) {
            return null;
        }

        String authorization = request.getHeader("Authorization");
        String token = StringUtils.substring(authorization, "bearer".length()).trim();
        Set<String> auths = null;

        try {
            auths = jwtTokenUtil.getAuthsFromToken(token);
        } catch (Exception e) {
            // 处理token过期
            if (e instanceof ExpiredJwtException) {
                requestContext.setResponseBody("token 过期");
                requestContext.setSendZuulResponse(false);
//                requestContext.setResponseStatusCode(401);
                return CommonResult.failed("token已过期，请重新登录");
            }
            e.printStackTrace();
        }
        //验证权限
        boolean b = auths.stream().anyMatch(auth -> StringUtils.equals(auth, uri));
        if (!b) {
            requestContext.setResponseBody("您没有权限");
            requestContext.setSendZuulResponse(false);
//            requestContext.setResponseStatusCode(403);
            return CommonResult.failed("您没有权限");
        }

        return null;
    }

}
